pub mod ident;

use core::ops::RangeInclusive;

use self::ident::Ident;

use super::{Elf64Addr, Elf64Half, Elf64Off, Elf64Word};

#[repr(C)]
pub struct Header {
    pub ident: Ident,
    _pad: [u8; 16 - core::mem::size_of::<Ident>()],
    pub obj_file_type: ObjFileType,
    pub machine: Machine,
    pub version: Version,
    pub entry: Elf64Addr,
    pub phoff: Elf64Off,
    pub shoff: Elf64Off,
    pub flags: Elf64Word,
    pub ehsize: Elf64Half,
    pub phentsize: Elf64Half,
    pub phnum: Elf64Half,
    pub shentsize: Elf64Half,
    pub shnum: Elf64Half,
    pub shstrndx: Elf64Half,
}

impl Header {
    /// section header table 在文件中的范围
    pub fn pht_range(&self) -> RangeInclusive<usize> {
        let start = self.phoff as usize;
        let end = start + (self.phentsize as usize * self.phnum as usize) - 1;
        start..=end
    }
    /// section header table 在文件中的范围
    pub fn sht_range(&self) -> RangeInclusive<usize> {
        let start = self.shoff as usize;
        let end = start + (self.shentsize as usize * self.shnum as usize) - 1;
        start..=end
    }
}

impl_borrow!(Header);

trans! {
    ObjFileType: u16,
    Version: u32,
    Machine: u16
}

def_const! {
    ObjFileType {
        NONE: 0,
        /// 可重定位的对象文件
        REL: 1,
        /// 可执行文件
        EXEC: 2,
        /// 可共享的对象文件
        DYN: 3,
        /// 核心文件
        CORE: 4
    }
    Version {
        CURRENT: 1
    }
    Machine {
        X86_64: 62
    }
}
